"""Logback 日志异常分析工具

分析 Logback 日志文件中的异常信息，合并相似异常并统计出现次数。

用法:
    python logbackfilter.py

功能:
    - 提取日志中的 Java 异常信息
    - 按时间戳分析异常
    - 合并 5 分钟内的相同异常
    - 统计异常出现次数

输入文件:
    当前目录下的 logback.log 文件

输出格式:
    时间: YYYY-MM-DD HH:MM:SS
    异常信息: 具体的异常堆栈
    产生次数: N
    ----------------

示例输出:
    时间: 2024-01-01 12:00:00
    异常信息: java.lang.NullPointerException: xxx
    产生次数: 3
    ----------------

注意:
    - 日志文件需要包含时间戳信息
    - 时间戳格式必须为: YYYY-MM-DD HH:MM:SS
    - 日志文件编码需要是 UTF-8"""

import re
from datetime import datetime, timedelta

def extract_exceptions(log_file_path):
    exceptions = []
    current_exception = []
    exception_pattern = re.compile(r'^\s*(java|javax|org)\.[\w.]+(Exception|Error):')
    end_pattern = re.compile(r'^\S')
    time_pattern = re.compile(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})')

    with open(log_file_path, 'r', encoding='utf-8') as file:
        for line in file:
            if exception_pattern.match(line):
                if current_exception:
                    exceptions.append('\n'.join(current_exception))
                    current_exception = []
                current_exception.append(line.strip())
            elif current_exception:
                if end_pattern.match(line):
                    exceptions.append('\n'.join(current_exception))
                    current_exception = []
                else:
                    current_exception.append(line.strip())

    if current_exception:
        exceptions.append('\n'.join(current_exception))

    merged_exceptions = []
    for exception in exceptions:
        match = time_pattern.search(exception)
        if match:
            timestamp = datetime.strptime(match.group(1), '%Y-%m-%d %H:%M:%S')
            message = re.sub(time_pattern, '', exception).strip()
            if not merged_exceptions:
                merged_exceptions.append((timestamp, message, 1))
            else:
                last_timestamp, last_message, last_count = merged_exceptions[-1]
                if message == last_message and (timestamp - last_timestamp) <= timedelta(minutes=5):
                    merged_exceptions[-1] = (last_timestamp, last_message, last_count + 1)
                else:
                    merged_exceptions.append((timestamp, message, 1))

    return merged_exceptions


log_file_path = 'logback.log'
merged_exceptions = extract_exceptions(log_file_path)

for timestamp, message, count in merged_exceptions:
    print(f"时间: {timestamp}")
    print(f"异常信息: {message}")
    print(f"产生次数: {count}")
    print('-' * 80)